home *** CD-ROM | disk | FTP | other *** search
- /*
- * llpar1.c
- *
- * Practical Algorithms for Image Analysis
- *
- * Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
- */
-
-
- /* PARALLELPAR: function takes start and end points of two parallel
- * lines and returns distance between lines and overlap
- * of lines
- * usage: overlapFlag =
- * parallelpar (ptO1, ptF1, ptO2, ptF2,
- * &dist, &overlap12)
- * OverlapFlag is 0 for no overlap, -1 for perpendicular
- * lines (which is also no overlap), and 1 for overlap.
- *
- * HISTORY
- * 4-Sept-85 Larry O'Gorman (log) at Bell Labs
- * This is the umpteenth time the parameter calculation has
- * been changed, and I'm getting a little tired of doing so.
- *
- * 26-Apr-85 Larry O'Gorman (log) at Bell Labs
- * Created.
- */
- #include <math.h>
- #include <stdlib.h>
- #include "lldef.h"
- #include "sal.h"
-
-
- #define OVERLAP 1 /* overlap exists */
- #define NOOVERLAP 0 /* no overlap exists */
- #define PERPENDICULAR -1 /* no nothing: lines are perpend. */
-
-
- int
- parallelpar (ptO1, ptF1, ptO2, ptF2, dist, overlap)
- struct point ptO1, /* initial and final pts of line 1 */
- ptF1, ptO2, /* initial and final pts of line 2 */
- ptF2;
-
- double *dist, /* perpendic. dist. between lines */
- *overlap; /* overlap between line segments */
-
- {
- register double deltaX1, /* run and rise of line 1 slope */
- deltaY1, deltaX2, /* run and rise of line 2 slope */
- deltaY2;
-
- struct { /* points on line 2 */
- double x, y;
- } pnts[4], midpt[2];
-
- double xO1, /* initial (O) and final (F) */
- yO1, /* points of lines 1 and 2 */
- xF1, yF1, xO2, yO2, xF2, yF2, xA2, /* intersection pts of perp. on line 2 */
- yA2, xB2, yB2, xM2, /* middle point of second line */
- yM2, max, /* max/min of 4 points on line 2 */
- min, numer, /* numerator and denominator */
- denom, /* of distance calculation */
- overlap2, /* absolute overlap on line 2 */
- length2, /* lenght of line 2 */
- temp;
-
- register long maxI, /* for ordering points */
- minI, i, j;
-
- int defined; /* 1 = overlap; 0 = none */
-
- /* initialize */
-
- xO1 = (double) ptO1.x;
- yO1 = (double) ptO1.y;
- xF1 = (double) ptF1.x;
- yF1 = (double) ptF1.y;
- xO2 = (double) ptO2.x;
- yO2 = (double) ptO2.y;
- xF2 = (double) ptF2.x;
- yF2 = (double) ptF2.y;
-
- deltaX1 = xF1 - xO1;
- deltaY1 = yF1 - yO1;
- deltaX2 = xF2 - xO2;
- deltaY2 = yF2 - yO2;
-
- /* intersection of perpendiculars from ends of line 1 to line 2 */
-
- temp = (deltaY2 * deltaY1 + deltaX1 * deltaX2);
- if (temp == 0.0)
- return (PERPENDICULAR);
-
- if (deltaX2 != 0.0) {
- xA2 = (1.0 / temp)
- * (xO1 * deltaX2 * deltaX1 + xO2 * deltaY2 * deltaY1
- + deltaX2 * deltaY1 * (yO1 - yO2));
- yA2 = (deltaY2 / deltaX2) * (xA2 - xO2) + yO2;
- xB2 = (1.0 / temp)
- * (xF1 * deltaX2 * deltaX1 + xO2 * deltaY2 * deltaY1
- + deltaX2 * deltaY1 * (yF1 - yO2));
- yB2 = (deltaY2 / deltaX2) * (xB2 - xO2) + yO2;
- }
- else {
- yA2 = (1.0 / temp)
- * (yO1 * deltaY2 * deltaY1 + yO2 * deltaX2 * deltaX1
- + deltaY2 * deltaX1 * (xO1 - xO2));
- xA2 = (deltaX2 / deltaY2) * (yA2 - yO2) + xO2;
- yB2 = (1.0 / temp)
- * (yF1 * deltaY2 * deltaY1 + yO2 * deltaX2 * deltaX1
- + deltaY2 * deltaX1 * (xF1 - xO2));
- xB2 = (deltaX2 / deltaY2) * (yB2 - yO2) + xO2;
- }
-
- /* test if intersection points fall outside of line segment 2 */
- /* if it does, set defined flag to indicate no overlap, BUT continue
- * with calculations to find direction of line 1 to 2 */
-
- defined = OVERLAP;
- if (deltaX2 != 0.0) {
- if (xA2 >= xO2 && xA2 >= xF2 && xB2 >= xO2 && xB2 >= xF2)
- defined = NOOVERLAP;
- else if (xA2 <= xO2 && xA2 <= xF2 && xB2 <= xO2 && xB2 <= xF2)
- defined = NOOVERLAP;
- }
- else {
- if (yA2 >= yO2 && yA2 >= yF2 && yB2 >= yO2 && yB2 >= yF2)
- defined = NOOVERLAP;
- else if (yA2 <= yO2 && yA2 <= yF2 && yB2 <= yO2 && yB2 <= yF2)
- defined = NOOVERLAP;
- }
-
- /* find the middle 2 pnts of overlap (or of no overlap, if none) on line 2 */
-
- pnts[0].x = xO2;
- pnts[0].y = yO2;
- pnts[1].x = xF2;
- pnts[1].y = yF2;
- pnts[2].x = xA2;
- pnts[2].y = yA2;
- pnts[3].x = xB2;
- pnts[3].y = yB2;
-
- if (deltaX2 == 0.0) {
- max = min = pnts[0].y;
- maxI = minI = 0;
- for (i = 1; i < 4; i++) {
- if (pnts[i].y > max) {
- maxI = i;
- max = pnts[i].y;
- }
- else if (pnts[i].y < min) {
- minI = i;
- min = pnts[i].y;
- }
- }
- }
- else {
- max = min = pnts[0].x;
- maxI = minI = 0;
- for (i = 1; i < 4; i++) {
- if (pnts[i].x > max) {
- maxI = i;
- max = pnts[i].x;
- }
- else if (pnts[i].x < min) {
- minI = i;
- min = pnts[i].x;
- }
- }
- }
- for (i = 0, j = 0; i < 4; i++) {
- if (i != minI && i != maxI) {
- midpt[j].x = pnts[i].x;
- midpt[j].y = pnts[i].y;
- j++;
- }
- }
-
- /* find dist from line 1 to midpt. of overlap segment on line 2 */
-
- xM2 = (midpt[0].x + midpt[1].x) / 2.0;
- yM2 = (midpt[0].y + midpt[1].y) / 2.0;
-
- if (deltaX1 == 0.0)
- *dist = xM2 - xO1;
- else if (deltaY1 == 0.0)
- *dist = yM2 - yO1;
- else {
- numer = (xM2 - xO1) - (yM2 - yO1) * deltaX1 / deltaY1;
- denom = sqrt ((deltaX1 * deltaX1) / (deltaY1 * deltaY1) + 1.0);
- *dist = numer / denom;
- }
-
- /* calculate overlap */
-
- overlap2 = (midpt[0].x - midpt[1].x) * (midpt[0].x - midpt[1].x)
- + (midpt[0].y - midpt[1].y) * (midpt[0].y - midpt[1].y);
- length2 = (xO2 - xF2) * (xO2 - xF2) + (yO2 - yF2) * (yO2 - yF2);
-
- *overlap = sqrt ((overlap2 / length2)) * 100.0;
-
- return (defined);
-
- }
-